/*
 * Copyright (c) 2020-2021. the original authors and DEPSEA.ORG
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.depsea.oss.client.aliyun;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.internal.OSSHeaders;
import com.aliyun.oss.model.*;
import org.depsea.oss.client.AbstractOssTemplate;
import org.depsea.oss.model.FileStreamInfo;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Wang Chengwei
 * @since 1.0.0 2021/12/1 17:36
 */
public abstract class AbstractAliyunOssTemplate extends AbstractOssTemplate {

    protected final OSSClient ossClient;

    protected AbstractAliyunOssTemplate(OSSClient ossClient) {
        this.ossClient = ossClient;
    }

    @Override
    protected void doUpload(long size, String bucketName, String fullPath, String originalFilename, String contentType, InputStream ins) {

        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fullPath, ins);
        putObjectRequest.setBucketName(bucketName);

        Map<String, String> userMetadata = new HashMap<>(1);
        userMetadata.put(OSSHeaders.OSS_PREFIX + "original-filename", URLEncoder.encode(originalFilename, StandardCharsets.UTF_8));

        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setUserMetadata(userMetadata);

        metadata.setContentType(contentType);
        metadata.setContentLength(size);
        metadata.setObjectAcl(CannedAccessControlList.Private);
        putObjectRequest.setMetadata(metadata);

        this.ossClient.putObject(putObjectRequest);
    }

    @Override
    protected FileStreamInfo doGetOssObject(String bucketName, String fullPath) throws IOException {
        GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, fullPath);

        OSSObject ossObject = this.ossClient.getObject(getObjectRequest);

        FileStreamInfo streamInfo = new FileStreamInfo();
        streamInfo.setContentType(ossObject.getObjectMetadata().getContentType());
        streamInfo.setFullPath(fullPath);
        String originalFilename = ossObject.getObjectMetadata().getUserMetadata().get(OSSHeaders.OSS_PREFIX + "original-filename");
        if (StringUtils.hasText(originalFilename)) {
            streamInfo.setOriginalFilename(URLDecoder.decode(originalFilename, StandardCharsets.UTF_8));
        }
        streamInfo.setSize(ossObject.getObjectMetadata().getContentLength());
        streamInfo.setFileExtension(StringUtils.getFilenameExtension(streamInfo.getOriginalFilename()));
        streamInfo.setFileData(ossObject.getObjectContent().readAllBytes());
        return streamInfo;
    }


    protected void deleteObject(String bucketName, String ossKey) {
        if (this.ossClient.doesObjectExist(bucketName, ossKey)) {
            this.ossClient.deleteObject(bucketName, ossKey);
        }
    }

}
